/*
 * mem_pool.h
 *
 *  Created on: 2016年9月7日
 *      Author: churchillyik
 */

#ifndef MEM_POOL_H_
#define MEM_POOL_H_

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include <pthread.h>

#define DEFAULT_BLOCK_SIZE 256
#define MEMPOOL_CACHE_LINE_SIZE (4 * 1024 * 1024)
#define MAX_WAIT_FOR_ALLOC_COUNTS 0xffffff

#pragma pack(push, 1) // 1字节对齐

typedef struct _memnode_s {
	struct _memnode_s *next;
} memnode_t, *lpmemnode_t;

#pragma pack(pop) // #pragma pack(push, 1) end

typedef struct _mempool_s {
	uint32_t block_bytes;
	uint32_t max_nb_blocks;
	uint32_t nb_total;
	uint32_t nb_in_use;
	uint32_t nb_in_queue;
	uint64_t memory_cost;
	lpmemnode_t head;
	lpmemnode_t tail;
	uint32_t nb_blocks_per_cache;
	uint32_t sz_blocks_per_cache;
	int refuse_alloc;
	uint32_t wait_for_alloc_cnts;
	void *cache_list;
	pthread_spinlock_t lock;
} mempool_t, *lpmempool_t;

// 取出节点的数据
#define MP_NODE_DATA(node) (uint8_t *)(&node[1])
// 取出节点的头指针
#define MP_NODE_HEAD_PTR(data) (lpmemnode_t)((uint8_t *)data - sizeof(memnode_t))
// 获得cache节点的下一个节点
#define MP_NEXT_CACHE(cache_node) (*(void **)(cache_node))

// 初始化内存池
extern lpmempool_t mempool_init(uint32_t nb_blocks, uint32_t max_nb_blocks, uint32_t block_bytes);
// 从内存池获得存储单元
extern lpmemnode_t mempool_alloc(lpmempool_t mempool);
// 归还内存池
extern int mempool_free(lpmempool_t mempool, lpmemnode_t node);
// 释放内存池
extern void mempool_destroy(lpmempool_t *pmempool);
// 打印内存池状态
extern void mempool_print(lpmempool_t mempool);


#endif /* MEM_POOL_H_ */
